
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package net.sf.odinms.scripting;

import net.sf.odinms.client.MapleClient;
import net.sf.odinms.scripting.rhinoEngine.RhinoScriptEngineFactory;
import net.sf.odinms.scripting.rhinoEngine.RhinoScriptEngineWrapper;
import org.mozilla.javascript.Context;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineFactory;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.lang.reflect.Method;

/**
 * @author Matze
 */
public abstract class AbstractScriptManager {

    protected ScriptEngine engine;
    private ScriptEngineManager sem;
    protected static final Logger log = LoggerFactory.getLogger(AbstractScriptManager.class);

    protected AbstractScriptManager() {

        sem = new ScriptEngineManager();
//        System.out.println("Available Script Engines:");
//        for (ScriptEngineFactory factory : sem.getEngineFactories()) {
//            System.out.println("--- Factory ---");
//            System.out.println("Engine Name: " + factory.getEngineName());
//            System.out.println("Language Name: " + factory.getLanguageName());
//            System.out.println("Extensions: " + factory.getExtensions());
//            System.out.println("Mime Types: " + factory.getMimeTypes());
//            System.out.println("Names: " + factory.getNames()); // <-- 这个最重要！
//        }
    }

    protected Invocable getInvocable(String path, MapleClient c) {
        try {
            path = "scripts/" + path;
            engine = null;
            if (c != null) {
                engine = c.getScriptEngine(path);
            }
            if (engine == null) {
                File scriptFile = new File(path);
                if (!scriptFile.exists()) {
                    return null;
                }
                // engine = sem.getEngineByName("javascript");
                // engine = new org.mozilla.javascript.engine.RhinoScriptEngineFactory().getScriptEngine();
                // engine = sem.getEngineByName("rhino");
                // 方法1：手动创建包装器
                engine = new RhinoScriptEngineWrapper(new RhinoScriptEngineFactory());
                if (c != null) {
                    c.setScriptEngine(path, engine);
                }
                FileReader fr = new FileReader(scriptFile);
                BufferedReader br = new BufferedReader(fr);
                String line = br.readLine();
                StringBuffer js = new StringBuffer();
                while (line != null) {
                    js.append(line);
                    js.append("\r\n");
                    line = br.readLine();
                }

                engine.eval(js.toString());
                br.close();
                fr.close();
            }
            // 诊断打印代码
            // ((RhinoScriptEngineWrapper)engine).diagnoseScope();
            return (Invocable) engine;
        } catch (Exception e) {
            log.error("Error executing script.", e);
            return null;
        }
    }

    protected void resetContext(String path, MapleClient c) {
        path = "scripts/" + path;
        c.removeScriptEngine(path);
    }
}
